/*
* Copyright 2013 Vishwa Patel
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License in the 'assets' directory of this
* application or at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.vishwa.pinit;
import java.io.IOException;
import java.util.List;
import java.util.Locale;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.BasicResponseHandler;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import android.app.SearchManager;
import android.content.ContentProvider;
import android.content.ContentValues;
import android.content.UriMatcher;
import android.database.Cursor;
import android.database.MatrixCursor;
import android.location.Address;
import android.location.Geocoder;
import android.net.Uri;
import android.net.http.AndroidHttpClient;
import android.provider.BaseColumns;
public class LocationSuggestionProvider extends ContentProvider {
private Geocoder mGeocoder;
public static final String AUTHORITY = "com.vishwa.pinit.search_suggestion_provider";
public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY + "/search");
private static final int SEARCH_SUGGEST = 1;
private static final AndroidHttpClient mAndroidHttpClient =
AndroidHttpClient.newInstance(LocationSuggestionProvider.class.getName());
private static final UriMatcher uriMatcher;
private static final String[] SEARCH_SUGGEST_COLUMNS = {
BaseColumns._ID,
SearchManager.SUGGEST_COLUMN_TEXT_1,
SearchManager.SUGGEST_COLUMN_TEXT_2,
SearchManager.SUGGEST_COLUMN_INTENT_DATA_ID
};
private String mGoogleGeocodingEndpoint = "http://maps.googleapis.com/maps/api/geocode/json?address=";
static {
uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
uriMatcher.addURI(AUTHORITY, SearchManager.SUGGEST_URI_PATH_QUERY, SEARCH_SUGGEST);
uriMatcher.addURI(AUTHORITY, SearchManager.SUGGEST_URI_PATH_QUERY + "/*", SEARCH_SUGGEST);
}
@Override
public int delete(Uri uri, String arg1, String[] arg2) {
throw new UnsupportedOperationException();
}
@Override
public String getType(Uri uri) {
switch (uriMatcher.match(uri)) {
case SEARCH_SUGGEST:
return SearchManager.SUGGEST_MIME_TYPE;
default:
throw new IllegalArgumentException("Unknown URL " + uri);
}
}
@Override
public Uri insert(Uri uri, ContentValues arg1) {
throw new UnsupportedOperationException();
}
@Override
public boolean onCreate() {
return true;
}
@Override
public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs,
String sortOrder) {
switch (uriMatcher.match(uri)) {
case SEARCH_SUGGEST:
String query = uri.getLastPathSegment();
MatrixCursor cursor = new MatrixCursor(SEARCH_SUGGEST_COLUMNS, 1);
if(Geocoder.isPresent()) {
try {
mGeocoder = new Geocoder(getContext(), Locale.ENGLISH);
List<Address> addressList = mGeocoder.getFromLocationName(query, 5);
for(int i = 0; i < addressList.size(); i++) {
Address address = addressList.get(i);
StringBuilder fullAddress = new StringBuilder();
for(int j = 1; j < address.getMaxAddressLineIndex(); j++) {
fullAddress.append(address.getAddressLine(j));
}
cursor.addRow(new String[] {Integer.toString(i),
address.getAddressLine(0).toString(),
fullAddress.toString(),
address.getLatitude()+","+address.getLongitude()});
}
return cursor;
}
catch (IllegalArgumentException e) {
return getLocationSuggestionsUsingAPI(query, cursor);
}
catch (IOException e) {
return getLocationSuggestionsUsingAPI(query, cursor);
}
}
default:
throw new IllegalArgumentException("Unknown Uri: " + uri);
}
}
private MatrixCursor getLocationSuggestionsUsingAPI(String query, MatrixCursor cursor){
String transformedQuery = query.replace(" ", "+");
String queryUrl = mGoogleGeocodingEndpoint + transformedQuery + "&sensor=false";
try {
JSONObject apiResponse = new JSONObject(mAndroidHttpClient.execute(new HttpGet(queryUrl),
new BasicResponseHandler()));
JSONArray results = (JSONArray) apiResponse.get("results");
for(int i = 0; i < results.length(); i++) {
String formattedAddress;
JSONObject result = results.getJSONObject(i);
if(result.has("formatted_address")) {
formattedAddress = result.getString("formatted_address");
if(result.has("geometry")) {
JSONObject geometry = result.getJSONObject("geometry");
if(geometry.has("location")) {
JSONObject location = geometry.getJSONObject("location");
double latitude = location.getDouble("lat");
double longitude = location.getDouble("lng");
cursor.addRow(new String[] {Integer.toString(i),
formattedAddress,
"",
latitude+","+longitude});
}
}
}
}
return cursor;
} catch (ClientProtocolException e) {
cursor.addRow(new String[] {"0", "Search is not available currently", "Try again later.", ""});
return cursor;
} catch (JSONException e) {
cursor.addRow(new String[] {"0", "Search is not available currently", "Try again later.", ""});
return cursor;
} catch (IOException e) {
cursor.addRow(new String[] {"0", "Search is not available currently", "Try again later.", ""});
return cursor;
}
}
@Override
public int update(Uri uri, ContentValues arg1, String arg2, String[] arg3) {
throw new UnsupportedOperationException();
}
}